import { useCallback, useState } from "react";
import { request } from "@/lib/utils/request";
import useFetchStream from "@/lib/hooks/useFetchStream";
import Messages from "@/components/Messages";
import MessageInput from "@/components/MessageInput";
import useChatStore from "@/store/chat";
import { toast } from "sonner";
import randomId from "@/lib/utils/randomID";
import { IResponseMessage, IUserMessage } from "@/lib/types";
import useLatestRef from "@/lib/hooks/useLatestRef";
import { apiHost } from "@/lib/constants";

export default function Home() {
  // const { id } = useParams<{ id: string }>();
  const [prompt, setPrompt] = useState("");
  const messageMapping = useChatStore((state) => state.messageMapping);
  const appendMessage = useChatStore((state) => state.appendMessage);
  const response = useChatStore((state) => state.response);
  const {
    isPending: isAnswering,
    refetch: sendPrompt,
    cancel: cancelGenerate,
  } = useFetchStream<{ query: string }>({
    onProgress(data) {
      // console.log(data);
      data.split("\n").forEach((line) => {
        const _line = line.trim();
        if (_line) {
          try {
            const json = JSON.parse(_line);
            if (json.type === "summary") {
              response(
                {
                  chunk: json.data.content,
                },
                json.data.done,
              );
            } else if (json.type === "source") {
              response({ source: json.data.source_urls }, true);
            } else if (json.type === "recommend") {
              response({ recommend: json.data.queries }, true);
            }
          } catch (err) {
            console.error(_line);
            console.error(err);
          }
        }
      });
    },
    onError(error) {
      response({ error }, true);
    },
    fetchFn: (data, signal) =>
      request(`${apiHost}/zs/query`, {
        signal,
        method: "post",
        params: data,
        stream: true,
      }),
  });

  const paramsRef = useLatestRef({
    isAnswering,
    sendPrompt,
    messageMapping,
    appendMessage,
  });
  const handleEdit = useCallback((content: string, parent: string | null) => {
    const { isAnswering, appendMessage, sendPrompt } = paramsRef.current;
    if (isAnswering) {
      toast.error("当前回答正在进行中，请取消后再试。");
      return;
    }
    const newUserMessage: IUserMessage = {
      id: randomId(),
      role: "user",
      content,
      timestamp: Date.now(),
    };
    const newResponseMessage: IResponseMessage = {
      id: randomId(),
      role: "assistant",
      content: "",
      recommend: [],
      source: [],
      done: false,
      timestamp: Date.now(),
    };
    appendMessage(newUserMessage, parent);
    appendMessage(newResponseMessage);
    sendPrompt({ query: content });
  }, []); // eslint-disable-line react-hooks/exhaustive-deps

  const handleSendPrompt = useCallback(
    (message?: string) => {
      message = message || prompt;
      if (!message) {
        return;
      }
      const userMessage: IUserMessage = {
        id: randomId(),
        role: "user",
        content: message,
        timestamp: Date.now(),
      };
      const responseMessage: IResponseMessage = {
        id: randomId(),
        role: "assistant",
        content: "",
        recommend: [],
        source: [],
        timestamp: Date.now(),
        done: false,
      };
      appendMessage(userMessage);
      appendMessage(responseMessage);
      sendPrompt({ query: message });
      setPrompt("");
    },
    [appendMessage, sendPrompt, prompt],
  );

  const handleRegenerate = useCallback((parent: string) => {
    const { isAnswering, sendPrompt, messageMapping, appendMessage } =
      paramsRef.current;
    if (isAnswering) {
      toast.error("当前回答正在进行中，请取消后再试。");
      return;
    }
    const question = messageMapping[parent];
    if (question.message.role !== "user") {
      return;
    }
    const newResponseMessage: IResponseMessage = {
      id: randomId(),
      role: "assistant",
      content: "",
      source: [],
      recommend: [],
      done: false,
      timestamp: Date.now(),
    };
    appendMessage(newResponseMessage, question.id);
    sendPrompt({ query: question.message.content });
  }, []); // eslint-disable-line react-hooks/exhaustive-deps

  return (
    <div className="flex min-h-0 min-w-0 flex-auto flex-col overflow-auto px-4 pt-4">
      <Messages
        isAnswering={isAnswering}
        onEdit={handleEdit}
        onClickRecommend={handleSendPrompt}
        onRegenerate={handleRegenerate}
      />
      <MessageInput
        isAnswering={isAnswering}
        prompt={prompt}
        onInput={setPrompt}
        onConfirmSend={handleSendPrompt}
        stopAnswering={cancelGenerate}
      />
    </div>
  );
}
